﻿using PGMHelper;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms.DataVisualization.Charting;

namespace HystereticBasic
{
    /// <summary>
    /// 延性系数计算基类
    /// </summary>
    public class DuctilityBasic
    {
        /// <summary>
        /// 正骨架曲线
        /// </summary>
        protected MontForceDispObj SkeletonObj { set; get; }

        /// <summary>
        /// 延性系数作图曲线
        /// </summary>
        protected ForceDispObj DuctilityFDObj { set; get; }

        /// <summary>
        /// 屈服点
        /// </summary>
        public ForceDispBasicPair YiledPoint { set; get; }

        /// <summary>
        /// 极限承载力点
        /// </summary>
        protected ForceDispBasicPair UltimatePoint { set; get; }

        /// <summary>
        /// 作图的Y轴线
        /// </summary>
        protected List<ForceDispBasicPair> LineYList { set; get; }

        /// <summary>
        /// 骨架峰值力
        /// </summary>
        protected float Mu
        {
            get
            {
                return this.SkeletonObj.ForceMaxPoint.Force;
            }
        }

        /// <summary>
        /// 屈服力
        /// </summary>
        public float YieldForce
        {
            get
            {
                return this.YiledPoint.Force;
            }
        }

        /// <summary>
        /// 屈服位移
        /// </summary>
        public float YieldDisp
        {
            get
            {
                return this.YiledPoint.Disp;
            }
        }

        /// <summary>
        /// 屈服延性系数
        /// </summary>
        public float YieldDucFactor
        {
            get
            {
                return this.YiledPoint.Disp == 0 ? 0 :
                    this.UltimatePoint.Disp / this.YiledPoint.Disp;
            }
        }

        /// <summary>
        /// 延性系数相关
        /// </summary>
        /// <param name="dataType"></param>
        /// <returns></returns>
        public float this[DataType dataType]
        {
            get
            {
                switch(dataType)
                {
                    case DataType.DuctilityYieldForce:
                        return this.YieldForce;
                    case DataType.DuctilityYieldDisp:
                        return this.YieldDisp;
                    case DataType.DuctilityFactor:
                        return this.YieldDucFactor;
                    default: return 0;
                }

            }
        }

        /// <summary>
        /// 绘图
        /// </summary>
        /// <param name="chart"></param>
        /// <param name="dMethod"></param>
        public void ToChart(Chart chart)
        {
            //清空序列数据
            chart.Series.Clear();
            //骨架曲线
            this.SkeletonObj.ToChart(chart, "骨架曲线", Color.Blue, 3);
            //等效屈服点求解过程
            this.DuctilityFDObj.ToChart(chart, "求解过程", Color.Red, 3, false);
            //遍历水平线 添加作图过程
            for(int i = 0; i < this.LineYList.Count; i++)
            {
                //构造对象
                var obj = new ForceDispObj();
                //获得点
                var pt = this.LineYList[i];
                //起始点
                var ptI = new ForceDispBasicPair(0, pt.Force);
                //添加点
                obj.Add(ptI); obj.Add(pt);
                //作图过程
                obj.ToChart(chart, "求解过程" + i, Color.Red, 3, false);
            }
            //函数指针添加点
            Action<string, Color, ForceDispBasicPair> addPt = (name, colr, pt) =>
            {
                chart.AddSeries(name, SeriesChartType.Point, colr);
                chart.Series[name].MarkerSize = 10;
                chart.Series[name].Points.DataBindXY(new List<float> { pt.Disp }, 
                    new List<float> { pt.Force });
            };
            //屈服点
            addPt("屈服点", Color.Blue, this.YiledPoint);
            //峰值点
            addPt("峰值点", Color.Green, this.SkeletonObj.ForceMaxPoint);
            //极限点
            addPt("极限点", Color.Red, this.UltimatePoint);
        }

        /// <summary>
        /// 初始化
        /// </summary>
        protected void initialForYield()
        {
            this.DuctilityFDObj = new ForceDispObj();
            this.DuctilityFDObj.Add(new ForceDispBasicPair());
            this.LineYList = new List<ForceDispBasicPair>();
            //添加峰值点
            this.LineYList.Add(this.SkeletonObj.ForceMaxPoint);
        }

        /// <summary>
        /// 设定屈服点
        /// </summary>
        /// <returns></returns>
        public virtual bool SetYieldPt()
        {
            return false;
        }

        /// <summary>
        /// 延性计算方法
        /// </summary>
        /// <returns></returns>
        public virtual DuctilityMethod GetMethod()
        {
            return DuctilityMethod.Unknow;
        }

        /// <summary>
        /// 空的构造函数
        /// </summary>
        public DuctilityBasic()
        {
            this.SkeletonObj = new MontForceDispObj();
            this.DuctilityFDObj = new ForceDispObj();
            this.YiledPoint = new ForceDispBasicPair();
            this.UltimatePoint = new ForceDispBasicPair();
            this.LineYList = new List<ForceDispBasicPair>();

            this.DuctilityFDObj.Add(new ForceDispBasicPair());
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="skeletonObj"></param>
        protected DuctilityBasic(MontForceDispObj skeletonObj, ForceDispBasicPair ultimatePoint) :this()
        {
            //复制数据
            this.SkeletonObj = skeletonObj;
            this.UltimatePoint = ultimatePoint;
        }
    }
}
